package xendit

import (
	"encoding/json"
	"errors"
	"log/slog"
	"time"

	"gitee.com/gxcc/go-utils/utils"
	"github.com/lib/pq"
)

// InvoiceRequest xendit集成支付 详见https://xendit.github.io/apireference/?bash#create-invoice
type InvoiceRequest struct {
	ExternalId      string `json:"external_id"` // transId
	PayerEmail      string `json:"payer_email"`
	Description     string `json:"description"`
	Amount          int64  `json:"amount"`
	ShouldSendEmail bool   `json:"should_send_email"`
	//CallbackVirtualAccountId string   `json:"callback_virtual_account_id"`
	InvoiceDuration int `json:"invoice_duration"`
	//SuccessRedirectUrl       string   `json:"success_redirect_url"`
	//FailureRedirectUrl       string   `json:"failure_redirect_url"`
	PaymentMethods []string `json:"payment_methods"`
}

type Invoice struct {
	Id                        string        `json:"id"`
	UserId                    string        `json:"user_id"`
	ExternalId                string        `json:"external_id"`
	Status                    string        `json:"status"`
	MerchantName              string        `json:"merchant_name"`
	MerchantProfilePictureUrl string        `json:"merchant_profile_picture_url"`
	Amount                    int64         `json:"amount"`
	PayerEmail                string        `json:"payer_email"`
	Description               string        `json:"description"`
	InvoiceUrl                string        `json:"invoice_url"`
	ExpiryDate                *time.Time    `json:"expiry_date"`
	AvailableBanks            []InvoiceBank `json:"available_banks" gorm:"-"`
	AvailableBanksIds         pq.Int64Array `json:"available_banks_ids" gorm:"type:bigint[]"`
	ShouldExcludeCreditCard   bool          `json:"should_exclude_credit_card"`
	ShouldSendEmail           bool          `json:"should_send_email"`
	Created                   *time.Time    `json:"created"`
	Updated                   *time.Time    `json:"updated"`
}

func (Invoice) TableName() string {
	return "xen_invoice"
}

//func WrapInvoice(invoice *Invoice) {
//	var bankList []InvoiceBank
//	app.DB.Where("invoice_id = ?", invoice.Id).Order("id asc").Find(&bankList)
//	invoice.AvailableBanks = bankList
//}

// 创建Invoice
func (svc *XenditSvc) CreateInvoice(externalId string, payerEmail string, description string, amount int64, duration int) (Invoice, error) {
	// 支持的虚拟银行列表
	var vaBankList = svc.VaBankList
	if len(vaBankList) == 0 {
		vaBankList = []string{"BRI", "MANDIRI", "BNI"}
	}
	var params = InvoiceRequest{
		ExternalId:      externalId,
		PayerEmail:      payerEmail,
		Description:     description,
		Amount:          amount,
		ShouldSendEmail: true,
		PaymentMethods:  vaBankList,
		InvoiceDuration: svc.InvoiceDuration,
	}
	if duration > 0 {
		params.InvoiceDuration = duration
	}
	url := "https://api.xendit.co/v2/invoices"
	headers := map[string]string{
		"Content-Type":  "application/json",
		"Authorization": svc.ApiKey,
	}

	req, err := json.Marshal(params)
	if err != nil {
		return Invoice{}, errors.New("create invoice failed")
	}

	res, err := utils.HttpPost(url, headers, req)
	if err != nil {
		return Invoice{}, errors.New("create invoice failed")
	}
	resMap := make(map[string]string)
	json.Unmarshal(res.Body, &resMap)
	if len(resMap["error_code"]) > 0 {
		var errorCode = resMap["error_code"]
		slog.Error("create invoice failed. err:" + errorCode)
		if errorCode == "EMAIL_FORMAT_ERROR" {
			return Invoice{}, errors.New("invalid email. please check your account email setting.")
		} else {
			return Invoice{}, errors.New(resMap["error_code"])
		}
	}
	var invoice Invoice
	json.Unmarshal(res.Body, &invoice)

	return invoice, nil
}
